package com.ezops.poc.processor;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.ezops.poc.bo.DynamicModel.Field;
import com.ezops.poc.bo.IClientModel;
import com.ezops.poc.util.EzopsConstants;
import com.ezops.poc.util.LoggerUtil;

/**
 * Camel-csv doesn't write the header and also requires the body of exchange to
 * be in <code>List<Map></code> format. This class transforms the client model
 * into the required format.
 * 
 * @author vgaurav
 * 
 */
@Component("clientModelCSVTransformer")
public class ClientModelCSVTransformer implements Processor {

	Logger logger = LoggerFactory.getLogger(ClientModelCSVTransformer.class);

	@Override
	public void process(Exchange exchange) throws Exception {
		logger.trace("Transformation of client model into camel-csv format starts");
		List<IClientModel> clientModels = exchange.getIn().getBody(List.class);
		List<Map<String, String>> convertedBody = new ArrayList<>();

		convertedBody.add(addHeader(exchange.getIn(), clientModels.get(0)));

		for (IClientModel clientModel : clientModels) {
			Map<String, String> row = new LinkedHashMap<>();
			Iterator<Field> fieldIterator = clientModel.iterator();
			while (fieldIterator.hasNext()) {
				Field field = fieldIterator.next();
				row.put(field.getName(), field.getValue());
			}
			convertedBody.add(row);
		}

		exchange.getIn().setBody(convertedBody);

		logger.trace("Transformation of client model into camel-csv format ends");

	}

	/**
	 * Add the header from which is stored in exchange header.
	 * 
	 * @param message
	 * @param model
	 * @return
	 */
	private Map<String, String> addHeader(Message message, IClientModel model) {
		Map<String, String> headerMap = new LinkedHashMap<>();

		Object fileHeadersObj = message.getHeader(EzopsConstants.FILE_HEADER);
		if (fileHeadersObj != null) {
			logger.debug("Found header in Exchange, using the same");
			String[] fileHeaders = (String[]) fileHeadersObj;
			for (String header : fileHeaders) {
				headerMap.put(header, header);
			}
		} else {
			logger.debug("Not found the header in Exchange, using the model data.");
			for (String header : model.getHeaders()) {
				headerMap.put(header, header);
			}
		}
		logger.debug("Exception records will have following headers"
				+ LoggerUtil.getLoggableFormat(headerMap));
		return headerMap;
	}

}
